package com.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.domain.entity.Address;
import com.domain.entity.Cart;
import com.domain.entity.Goods;
import com.domain.entity.User;
import com.domain.req.AddCartReq;
import com.domain.req.PageReq;
import com.domain.req.UpdateGoodsSumReq;
import com.exception.ServiceException;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mapper.CartMapper;
import com.mapper.GoodsMapper;
import com.service.AddressService;
import com.service.CartService;
import com.service.GoodsService;
import com.utils.JWTUtils;
import com.utils.ValidatorUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * @author caishenao
 * @description 针对表【cart】的数据库操作Service实现
 * @createDate 2023-10-12 20:12:25
 */
@Service
@Slf4j
public class CartServiceImpl implements CartService {

    @Autowired
    private AddressService addressService;

    @Autowired
    private GoodsService goodsService;

    @Resource
    private CartMapper cartMapper;
    @Resource
    private GoodsMapper goodsMapper;

    /**
     * 添加商品到自己的购物车
     *
     * @param addCartReq 添加的请求
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addCart(AddCartReq addCartReq) {
        // 1. 数据校验
        ValidatorUtils.validateEntity(addCartReq);

        // 2. 判断地址是否存在
        Address address = addressService.getById(addCartReq.getAddressId());
        if (address == null) {
            log.error("id为{}的地址不存在", JSONObject.toJSONString(addCartReq.getAddressId()));
            throw new ServiceException("地址已被删除或");
        }

        // 3. 判断商品是否存在
        Goods goods = goodsMapper.getById(addCartReq.getGoodsId());
        if (goods == null) {
            log.error("id为:{}的商品不存在!", JSONObject.toJSONString(addCartReq.getGoodsId()));
            throw new ServiceException("商品不存在!");
        }

        // 4. 判断商品库存是否够用（不扣减库存）
        if (goods.getStock() < addCartReq.getGoodsSum()) {
            // 库存不足
            log.error("商品:{}的库存不足", JSONObject.toJSONString(goods));
            throw new ServiceException("库存不足!");
        }

        // 5. 转换为购物车实体
        // 获取当前登录用户
        User currentUser = JWTUtils.getCurrentUser();
        Cart cart = addCartReqConversion(addCartReq, currentUser);

        // 6. 新增进数据库
        cartMapper.insert(cart);
    }

    /**
     * 查询本人所有购物车信息
     *
     * @return 本人购物车信息
     */
    @Override
    public List<Cart> list() {
        User currentUser = JWTUtils.getCurrentUser();
        return cartMapper.list(currentUser.getId());
    }

    /**
     * 根据购物车id删除购物车信息
     *
     * @param id 购物车id
     */
    @Override
    public void deleteById(Integer id) {
        // 1. 判断购物车信息是否存在
        // 获取当前登录用户
        User currentUser = JWTUtils.getCurrentUser();
        Cart cart = cartMapper.getByIdAndUserId(id, currentUser.getId());
        if (cart == null) {
            log.error("购物车信息不存在!");
            throw new ServiceException("购物车信息不存在!");
        }

        // 2. 根据id删除
        cartMapper.deleteByIdAndUserId(id, currentUser.getId());
    }

    /**
     * 清空购物车
     */
    @Override
    public void deleteAll() {
        // 1. 获取当前登录用户
        User currentUser = JWTUtils.getCurrentUser();

        // 2. 清空本人所有购物车
        cartMapper.deleteByUserId(currentUser.getId());
    }

    /**
     * 修改商品数量
     *
     * @param updateGoodsSumReq 修改商品数量请求
     */
    @Override
    public void updateGoodsSum(UpdateGoodsSumReq updateGoodsSumReq) {
        // 1. 数据校验
        ValidatorUtils.validateEntity(updateGoodsSumReq);

        // 2. 判断购物车是否存在
        // 获取当前用户
        User currentUser = JWTUtils.getCurrentUser();
        Cart cart = cartMapper.getByIdAndUserId(updateGoodsSumReq.getId(), currentUser.getId());
        if (cart == null) {
            // 购物车不存在
            log.error("购物车id为:{}的购物车信息不存在!", JSONObject.toJSONString(updateGoodsSumReq.getId()));
            throw new ServiceException("购物车信息不存在！");
        }

        // 3. 判断商品是否又库存
        Goods goods = goodsMapper.getById(cart.getGoodsId());
        if (goods == null) {
            // 商品信息不存在
            log.error("id为:{}的商品信息不存在", JSONObject.toJSONString(cart.getGoodsId()));
            throw new ServiceException("商品信息已被删除");
        }
        if (goods.getStock() < updateGoodsSumReq.getGoodsSum()) {
            // 商品库存不足
            log.error("商品:{}的不存不足", JSONObject.toJSONString(goods));
            throw new ServiceException("库存不足!");
        }

        // 4. 修改数据库
        cart = updateGoodsSumReqConversion(updateGoodsSumReq, currentUser);
        cartMapper.updateSelect(cart);
    }

    /**
     * 分页查询购物车信息
     *
     * @param pageReq 分页请求
     * @return 分页类型的购物车信息
     */
    @Override
    public PageInfo<Cart> pageList(PageReq pageReq) {
        // 1. 日志打印
        log.info("访问分页查询购物车信息，请求入参:{}", JSONObject.toJSONString(pageReq));

        // 2. 开始分页
        PageHelper.startPage(pageReq.getPageNum(), pageReq.getPageSize());
        // 3. 获取当前登录用户
        User currentUser = JWTUtils.getCurrentUser();
        List<Cart> list = cartMapper.list(currentUser.getId());
        for (Cart cart : list) {
            // 查询商品数据和地址数据
            Goods goods = goodsMapper.getById(cart.getGoodsId());
            Address address = addressService.getById(cart.getAddressId());
            cart.setGoods(goods);
            cart.setAddress(address);
        }
        PageInfo<Cart> cartPageInfo = new PageInfo<>(list);
        log.info("访问分页查询购物车信息，出参:{}", JSONObject.toJSONString(cartPageInfo));
        return cartPageInfo;
    }

    /**
     * 获取本用户的总钱数
     *
     * @return 购物的总钱数
     */
    @Override
    public Double getTotalMoney() {
        // 1. 获取当前登录用户
        User currentUser = JWTUtils.getCurrentUser();

        // 2. 查询并计算
        return cartMapper.getTotalMoneyByUserId(currentUser.getId());
    }

    /**
     * 修改商品数量转换
     *
     * @param updateGoodsSumReq 修改商品数据请求
     * @param currentUser       当前登录用户
     * @return 转换的购物车信息
     */
    private Cart updateGoodsSumReqConversion(UpdateGoodsSumReq updateGoodsSumReq, User currentUser) {
        Cart cart = new Cart();
        cart.setId(updateGoodsSumReq.getId());
        cart.setGoodsSum(updateGoodsSumReq.getGoodsSum());
        cart.setUserId(currentUser.getId());
        return cart;
    }

    /**
     * 将新增购物车请求转换为购物车对象
     *
     * @param addCartReq  新增购物车请求
     * @param currentUser 当前登录用户
     * @return 要新增的购物车
     */
    private Cart addCartReqConversion(AddCartReq addCartReq, User currentUser) {
        Cart cart = new Cart();
        cart.setUserId(currentUser.getId());
        cart.setId(addCartReq.getGoodsId());
        cart.setAddressId(addCartReq.getAddressId());
        cart.setGoodsSum(addCartReq.getGoodsSum());
        cart.setGoodsId(addCartReq.getGoodsId());
        cart.setCreateTime(new Date());
        return cart;
    }
}




